package edu.ilstu.mind.ise.ccp.examples;

import edu.ilstu.mind.ise.ccp.CentralControlProcessor;
import edu.ilstu.mind.ise.ccp.impl.disruptor.DisruptorCentralControlProcessor;
import edu.ilstu.mind.ise.ccp.logger.LoggerFactory;
import edu.ilstu.mind.ise.ccp.logger.LoggerLevel;
import edu.ilstu.mind.ise.ccp.logger.console.ConsoleLoggerFactory;
import edu.ilstu.mind.ise.ccp.message.Message;
import edu.ilstu.mind.ise.ccp.message.MutableMessage;
import edu.ilstu.mind.ise.ccp.mindmodule.DummyMindModule;
import edu.ilstu.mind.ise.ccp.mindmodule.MindModule;
import edu.ilstu.mind.ise.ccp.module.AbstractModule;

public class SimpleCcpExample {
	public static void main(String[] args) {
		// Create the logger factory
		LoggerFactory loggerFactory = new ConsoleLoggerFactory(LoggerLevel.DEBUG);
		//LoggerFactory loggerFactory = new GuiLoggerFactory(LoggerLevel.DEBUG, new String[] { "CCP", "MIND_MODULE" });

		// Create the CCP and assign its logger
		CentralControlProcessor ccp = new DisruptorCentralControlProcessor();
		ccp.setLogger(loggerFactory.createLogger("CCP"));

		// Create the Mind Module and Sender/Receiver Modules and assign loggers
		MindModule mindModule = new DummyMindModule();
		mindModule.setLogger(loggerFactory.createLogger("MIND_MODULE"));
		SenderModule senderModule = new SenderModule();
		senderModule.setLogger(loggerFactory.createLogger("SENDER"));
		ReceiverModule receiverModule = new ReceiverModule();
		receiverModule.setLogger(loggerFactory.createLogger("RECEIVER"));

		// Add the Modules to the CCP
		ccp.setMindModule(mindModule);
		ccp.addModule("SENDER", senderModule);
		ccp.addModule("RECEIVER", receiverModule);

		// Initialize the CCP
		ccp.init();
	}

	private static class SenderModule extends AbstractModule {
		@Override
		public void init() {
			// Create and start the send thread
			new SendThread().start();
		}

		@Override
		public boolean onMessage(Message message) {
			// do nothing
			return true;
		}

		private class SendThread extends Thread {
			@Override
			public void run() {
				// Loop indefinitely
				while (true) {
					try {
						// Wait 2 seconds
						Thread.sleep(2000);
						// Create and populate the message
						MutableMessage message = createMessage("RECEIVER", 1);
						message.setField("TEXT", "Time:" + System.currentTimeMillis());
						// Log and Send the message to the Receiver Module
						getLogger().info("Sending: " + message.getStringField("TEXT"));
						sendMessage(message);
					} catch (InterruptedException e) {
					}
				}
			}
		}
	}

	private static class ReceiverModule extends AbstractModule {
		@Override
		public void init() {
			// do nothing
		}

		@Override
		public boolean onMessage(Message message) {
			// Log the received message
			getLogger().info("Received Message - From:<" + message.getFrom() + "> Text:<" + message.getStringField("TEXT") + ">");
			return true;
		}
	}
}